package cn.cangfei.massage.service.impl;

import cn.cangfei.massage.constant.RedisConstants;
import cn.cangfei.massage.dto.MassageDoctorDTO;
import cn.cangfei.massage.dto.VisitPlanResiduesDTO;
import cn.cangfei.massage.dto.custom.MassageDoctorDTOFinal;
import cn.cangfei.massage.dto.param.MassageDoctorParam;
import cn.cangfei.massage.entity.MassageDoctor;
import cn.cangfei.massage.entity.MassageDoctorExample;
import cn.cangfei.massage.entity.MassageInfo;
import cn.cangfei.massage.exception.YyghException;
import cn.cangfei.massage.mapper.MassageDoctorMapper;
import cn.cangfei.massage.mapper.MassageInfoMapper;
import cn.cangfei.massage.service.*;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Lemon  2313812755@qq.com
 * @date 2023/2/4
 */
@Service
public class MassageDoctorInfoServiceImpl implements IMassageDoctorService {

    @Resource
    private MassageDoctorMapper doctorInfoMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;


    @Resource
    private MassageInfoMapper massageInfoMapper;
    @Resource
    private IMassageSpecialService specialService;

    @Resource
    private IMassageOutpatientService outpatientService;

    @Resource
    private IMassageInfoService massageInfoService;


    @Resource
    private IVisitPlanService visitPlanService;

    @Resource
    private IPowerAccountService accountService;


    /**
     * 添加师傅信息
     *
     * @param param 师傅信息参数
     * @return 是否成功
     */
    @Override
    public boolean insert(MassageDoctorParam param) {
        MassageDoctor info = new MassageDoctor();

        BeanUtils.copyProperties(param, info);

        info.setGmtCreate(new Date());
        info.setGmtModified(new Date());

        return doctorInfoMapper.insertSelective(info) > 0;
    }

    /**
     * 更新师傅信息
     *
     * @param id    师傅编号
     * @param param 师傅信息参数
     * @return 是否成功
     */
    @Override
    public boolean update(Long id, MassageDoctorParam param) {

        /*MassageDoctor massageDoctor = doctorInfoMapper.selectByPrimaryKey(id);
        String name = massageDoctor.getName();
        Long massageId = massageDoctor.getMassageId();
        if (name.equals(param.getName()) && Objects.equals(massageId, param.getMassageId())) {

        } else {
            // 则要判断
            Integer count = doctorInfoMapper.count(param.getName(), param.getMassageId());
            if (count > 0) {
                throw new YyghException(500, "该店铺下已存在该师傅姓名");
            }
        }*/

        MassageDoctor info = new MassageDoctor();

        BeanUtils.copyProperties(param, info);

        info.setId(id);
        info.setGmtModified(new Date());

        // 删除redis中的数据
        String key = RedisConstants.DOCTOR_INFO_PREFIX + id;
        stringRedisTemplate.delete(key);

        return doctorInfoMapper.updateByPrimaryKeySelective(info) > 0;
    }

    /**
     * 是否存在师傅信息
     *
     * @param id 师傅编号
     * @return 是否存在
     */
    @Override
    public boolean count(Long id) {
        MassageDoctorExample example = new MassageDoctorExample();

        example.createCriteria()
                .andIdEqualTo(id);

        return doctorInfoMapper.countByExample(example) > 0;
    }

    /**
     * 获取转换后的对象信息
     *
     * @param id 师傅编号
     * @return 转换后的对象
     */
    @Override
    public Optional<MassageDoctorDTO> getConvert(Long id) {
        return Optional.ofNullable(convert(doctorInfoMapper.selectByPrimaryKey(id)));
    }

    /**
     * 获取师傅名称
     *
     * @param id 师傅编号
     * @return 师傅名称，空则，返回未知
     */
    @Override
    public String getName(Long id) {
        return getOptional(id).map(MassageDoctor::getName).orElse("未知");
    }

    /**
     * 获取师傅信息
     *
     * @param id 师傅编号
     * @return 师傅编号
     */
    @Override
    public Optional<MassageDoctor> getOptional(Long id) {
        return Optional.ofNullable(doctorInfoMapper.selectByPrimaryKey(id));
    }

    /**
     * 删除师傅信息
     *
     * @param id 师傅编号
     * @return 是否成功
     */
    @Transactional
    @Override
    public boolean delete(Long id) {
        // 去出诊计划表里面 必须没有出诊计划才行
        Integer count = visitPlanService.getPlanByDoctorId(id);
        if (count > 0) {
            throw new YyghException(500, "请删除该师傅的出诊计划再删除!");
        }
        // 删除redis中的数据
        String key = RedisConstants.DOCTOR_INFO_PREFIX + id;
        stringRedisTemplate.delete(key);
        // 还要删除师傅的账号才行
        accountService.deleteByDoctorId(id);
        return doctorInfoMapper.deleteByPrimaryKey(id) > 0;
    }

    /**
     * 查找师傅信息
     *
     * @param name     师傅名称
     * @param pageNum  第几页
     * @param pageSize 页大小
     * @return 师傅信息列表
     */
    @Override
    public List<MassageDoctorDTO> list(String name, Integer pageNum, Integer pageSize, Long massageId) {

        PageHelper.startPage(pageNum, pageSize);

        MassageDoctorExample example = new MassageDoctorExample();

        if (!StringUtils.isEmpty(name)) {
            example.createCriteria()
                    .andNameLike("%" + name + "%");
        }

        List<MassageDoctor> massageDoctors = doctorInfoMapper.selectByExample(example);
        // 删选是否为这个学校id
        if (massageId != null) {

            // filter就是表示不要的
            massageDoctors = massageDoctors.stream().filter((item) -> {
                System.out.println(item.getMassageId());
                return !Objects.equals(item.getMassageId(), massageId);
            }).collect(Collectors.toList());
        }

        return massageDoctors.stream()
                .map(this::convert)
                .collect(Collectors.toList());
    }

    /**
     * 查找师傅信息列表
     *
     * @param name         师傅名称
     * @param specialId    专科编号
     * @param outpatientId 门诊编号
     * @param pageNum      第几页
     * @param pageSize     页大小
     * @return 师傅信息列表
     */
    @Override
    public List<MassageDoctorDTO> list(String name, Long specialId, Long outpatientId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);

        MassageDoctorExample example = new MassageDoctorExample();

        MassageDoctorExample.Criteria criteria = example.createCriteria();

        if (!StringUtils.isEmpty(name)) {
            criteria.andNameLike("%" + name + "%");
        }

        if (specialId != null) {
            criteria.andSpecialIdEqualTo(specialId);
        }

        if (outpatientId != null) {
            criteria.andOutpatientIdEqualTo(outpatientId);
        }

        return doctorInfoMapper.selectByExample(example).stream()
                .map(this::convert)
                .collect(Collectors.toList());
    }

    @Override
    public List<MassageDoctorDTO> getDoctorByMassageId1(Long massageId, String week, String days) {
        /*List<MassageSpecial> list = specialService.list(massageId, 1, 100);

        // 获取了所有的special
        List<Long> specialIds = list.stream().map(item -> {
            return item.getId();
        }).collect(Collectors.toList());*/

        // 现在不用获取科室id 直接根据massageId来实现就可以了

        // 根据massageId来获取所有师傅的信息
        List<MassageDoctorDTO> doctorDTOS = doctorInfoMapper.getInfoByMassageId(massageId);

        // 将收集出来的来看看
        List<MassageDoctorDTO> collect = doctorDTOS.stream().filter((item) -> {
            String day = item.getDay();
            // 还要看今天是否是属于这个星期
            String[] split = day.split(",");
            List<String> list1 = Arrays.asList(split);
            return list1.contains(week);
        }).collect(Collectors.toList());

        if (collect.size() > 0) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            // 今天的月日
            Date date = new Date(); // 2022-21-23
            // 找不包含的

//            System.out.println("format:" + format);
            List<MassageDoctorDTO> doctorDTOS1 = collect.stream().filter((item) -> {
                String jia = item.getJia();
                if (StringUtils.isEmpty(jia)) {
                    return true;
                } else {
                    String[] split = jia.split(",");
                    // 里面的就是年-月-日
                    List<String> list1 = Arrays.asList(split);
                    return !list1.contains(days);
                }
            }).collect(Collectors.toList());


            return doctorDTOS1;
        }


        return collect;


    }

    @Override
    public List<MassageDoctorDTOFinal> getDoctorByMassageId(Long massageId, String week, String days) {
        /*List<MassageSpecial> list = specialService.list(massageId, 1, 100);

        // 获取了所有的special
        List<Long> specialIds = list.stream().map(item -> {
            return item.getId();
        }).collect(Collectors.toList());*/

        // 现在不用获取科室id 直接根据massageId来实现就可以了

        // 根据massageId来获取所有师傅的信息
        // 先从缓存里面获取
        String keyPrefix = RedisConstants.DOCTOR_INFO_PREFIX;
        // 从redis中获取这个前缀所有的value
        Set<String> keys = stringRedisTemplate.keys(keyPrefix + "*");
        List<MassageDoctorDTO> doctorDTOS = new ArrayList<>();
        if (keys != null && !keys.isEmpty()) {
            // 从redis中获取
            for (String key : keys) {
                String value = stringRedisTemplate.opsForValue().get(key);
                MassageDoctorDTO massageDoctorDTO = JSONUtil.toBean(value, MassageDoctorDTO.class);
                doctorDTOS.add(massageDoctorDTO);
            }
        } else {
            // 从数据库中获取
            doctorDTOS = doctorInfoMapper.getInfoByMassageId(massageId);
            // 将数据放入redis中
            for (MassageDoctorDTO doctorDTO : doctorDTOS) {
                String key = keyPrefix + doctorDTO.getId();
                stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(doctorDTO));
            }
        }

        // List<MassageDoctorDTO> doctorDTOS = doctorInfoMapper.getInfoByMassageId(massageId);

        // 将收集出来的来看看
        List<MassageDoctorDTO> collect = doctorDTOS.stream().filter((item) -> {
            String day = item.getDay();
            // 还要看今天是否是属于这个星期
            String[] split = day.split(",");
            List<String> list1 = Arrays.asList(split);
            return list1.contains(week);
        }).collect(Collectors.toList());

        if (!collect.isEmpty()) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            // 今天的月日
            Date date = new Date(); // 2022-21-23
            // 找不包含的

//            System.out.println("format:" + format);
            List<MassageDoctorDTO> doctorDTOS1 = collect.stream().filter((item) -> {
                String jia = item.getJia();
                if (StringUtils.isEmpty(jia)) {
                    return true;
                } else {
                    String[] split = jia.split(",");
                    // 里面的就是年-月-日
                    List<String> list1 = Arrays.asList(split);
                    return !list1.contains(days);
                }
                // 进行排序以后就是这个默认的顺序
            }).sorted((item1, item2) -> {
                return item1.getId().compareTo(item2.getId());
            }).collect(Collectors.toList());

            // 先收集为一个map
            HashMap<Long, VisitPlanResiduesDTO> map = new HashMap<>();
            doctorDTOS1.forEach(item -> {
                Long doctorId = item.getId();
                List<VisitPlanResiduesDTO> doctorPlanByDate = visitPlanService.getDoctorPlanByDate(massageId, doctorId, week, days);
                if (!doctorPlanByDate.isEmpty()) {
                    VisitPlanResiduesDTO visitPlanResiduesDTO = doctorPlanByDate.get(0);
                    map.put(doctorId, visitPlanResiduesDTO);
                }
            });

            // 封装某天某个师傅出诊情况
            List<MassageDoctorDTOFinal> collect1 = doctorDTOS1.stream().map(item -> {
                MassageDoctorDTOFinal massageDoctorDTOFinal = new MassageDoctorDTOFinal();
                BeanUtils.copyProperties(item, massageDoctorDTOFinal);
                // 根据massageId, doctorId, week, date来查询出诊情况
                // 每个师傅的出诊情况
                //List<VisitPlanResiduesDTO> doctorPlanByDate = visitPlanService.getDoctorPlanByDate(massageId, item.getId(), week, days);
                VisitPlanResiduesDTO visitPlanResiduesDTO = map.get(item.getId()) == null ? new VisitPlanResiduesDTO() : map.get(item.getId());
                /*VisitPlanResiduesDTO visitPlanResiduesDTO = new VisitPlanResiduesDTO();
                if (doctorPlanByDate.size() > 0) {
                    for (VisitPlanResiduesDTO planResiduesDTO : doctorPlanByDate) {
                        if (Objects.equals(planResiduesDTO.getDoctorId(), item.getId())) {
                            visitPlanResiduesDTO = planResiduesDTO;
                            break;
                        }
                    }
                }*/
                massageDoctorDTOFinal.setVisitPlanResiduesDTOS(visitPlanResiduesDTO);
//                massageDoctorDTOFinal.setVisitPlanResiduesDTOS(doctorPlanByDate);

                // 根据师傅id来查询出诊计划id
                return massageDoctorDTOFinal;
            }).collect(Collectors.toList());

            return collect1;
        }


//        return collect;
        return null;


    }

    @Override
    public Integer getDoctorByMassageId(Long massageId) {
        Integer count = doctorInfoMapper.getDoctorByMassageId(massageId);
        return count;

    }

    /**
     * 根据massageId查询这个推拿馆的师傅
     *
     * @param massageId
     * @param name
     * @return
     */
    @Override
    public List<MassageDoctorDTO> getDoctorByMassageId(Long massageId, String name, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<MassageDoctorDTO> doctorDTOS;
        if (StringUtils.isEmpty(name)) {
            // 根据massageId来获取所有师傅的信息
            doctorDTOS = doctorInfoMapper.getInfoByMassageIds(massageId);
        } else {
            // 根据根据massageId来获取所有师傅的信息和name来模糊查询
            doctorDTOS = doctorInfoMapper.getInfoByMassageIdAndName(massageId, "%" + name + "%");
        }
        return doctorDTOS;
    }

    /**
     * 查询全部师傅信息
     *
     * @return
     */
    @Override
    public List<MassageDoctor> getAllDoctor() {
        MassageDoctorExample massageDoctorExample = new MassageDoctorExample();
        List<MassageDoctor> massageDoctors = doctorInfoMapper.selectByExample(massageDoctorExample);

        return massageDoctors;
    }

    @Override
    public boolean countMassageId(Long massageId) {
        LambdaQueryWrapper<MassageInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(MassageInfo::getId, massageId);
        Integer integer = massageInfoMapper.selectCount(lambdaQueryWrapper);
        return integer > 0;
    }

    @Override
    public List<MassageDoctorDTO> getDoctorByMassageIdForAdmin(Long massageId, String week, String days) {
        // 根据massageId来获取所有师傅的信息
        List<MassageDoctorDTO> doctorDTOS = doctorInfoMapper.getInfoByMassageId(massageId);


        if (doctorDTOS.size() > 0) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            // 今天的月日
            Date date = new Date(); // 2022-21-23
            // 找不包含的

//            System.out.println("format:" + format);
            List<MassageDoctorDTO> doctorDTOS1 = doctorDTOS.stream().filter((item) -> {
                String jia = item.getJia();
                if (StringUtils.isEmpty(jia)) {
                    return true;
                } else {
                    String[] split = jia.split(",");
                    // 里面的就是年-月-日
                    List<String> list1 = Arrays.asList(split);
                    return !list1.contains(days);
                }
            }).collect(Collectors.toList());
            return doctorDTOS1;
        }
        return doctorDTOS;
    }

    /**
     * 转换师傅信息
     * 增加专科名称，门诊名称
     *
     * @param doctor 师傅信息
     * @return 师傅信息封装对象
     */
    private MassageDoctorDTO convert(MassageDoctor doctor) {


        MassageDoctorDTO dto = new MassageDoctorDTO();


        BeanUtils.copyProperties(doctor, dto);

        // 设置专科名称
        dto.setSpecialName(specialService.getName(doctor.getSpecialId()));

        // 设置门诊名称
        dto.setOutpatientName(outpatientService.getName(doctor.getOutpatientId()));

        // 设置推拿馆名称
        dto.setMassageName(massageInfoService.getName(doctor.getMassageId()));
        Long massageId = doctor.getMassageId();
        Optional<MassageInfo> optional = massageInfoService.getOptional(massageId);
        if (optional.isPresent()) {
            MassageInfo massageInfo = optional.get();
            dto.setAddress(massageInfo.getAddress());

        }
        // 设置时间段
        dto.setDuan(visitPlanService.getDuan(dto.getId()));
        // 设置day
        dto.setDay(visitPlanService.getDay(dto.getId()));
        // 设置jia
        dto.setJia(visitPlanService.getJia(dto.getId()));

        return dto;
    }
}
